module ext.functional;


/***************************************
Returns $(D true).
 */
template staticYes(lst...)
{
    enum bool staticYes = true;
}


/***************************************
Returns $(D true) if $(D fun(args)) _throws an exception.
 */
template throws(alias fun)
{
    ///
    bool throws(T...)(T args) nothrow
    {
        try
        {
            // to prevent optimization for pure function call
            static typeof(fun(args)) invoke(T args)
            {
                return fun(args);
            }
            invoke(args);
            return false;
        }
        catch
        {
            return true;
        }
    }
}
// [workaround] fun is not accessible from functional
package enum string _throws_code =
q{
    template throws(alias fun)
    {
        ///
        bool throws(T...)(T args) nothrow
        {
            try
            {
                // to prevent optimization for pure function call
                static typeof(fun(args)) invoke(T args)
                {
                    return fun(args);
                }
                invoke(args);
                return false;
            }
            catch
            {
                return true;
            }
        }
    }
};

unittest
{
    static int foo(int n) pure
    {
        if (n < 0)
            throw new Exception("");
        return n;
    }
    assert( throws!foo(-1));
    assert(!throws!foo( 0));
}


